/*****************************************************************************/
/*	File: mmLCD.c
/*	Purpose: Contains functions for controlling and configuring Mentor LCD
/*	Creation Date:  6/11/2011
/*	Eng: Jason Reber
/*****************************************************************************/

#include <pic.h>
#include "mmLCD.h"
#include "GenericTypeDefs.h"

const SEVEN_SEGMENT_TYPE segment_data[] = {DIGIT_0, DIGIT_1, DIGIT_2, DIGIT_3,
                                             DIGIT_4, DIGIT_5, DIGIT_6, DIGIT_7, 
                                             DIGIT_8, DIGIT_9};

void mmLCDInit(void);




/****************************************************************************
  Function:
    void mmLCDInit(void)

  Summary:
    Initializes the LCD peripheral for the F1 Evaluation Platform

  Description:
    This function configures the LCD peripheral for:
    Type B Waveform,
    Timer 1 Oscillator, and 
    1:1 prescaler
    All segment data is cleared.  The segments enables are configured for
    the Mentor LCD per circuit design.
 
  Precondition:
    None

  Parameters:
    None

  Returns:
    None

  Remarks:
    Type B waverorm was used to allow the LCDIF flag to be the RTCC source.
    This feature was needed when operating the BLDC motors because Timer 1
    is needed for accurate commutation time and cannot be used for RTCC.
  ***************************************************************************/
void mmLCDInit(void)
{
 /*configure the LCD Phase Register*/
    LCDPS = 0;		//clear the LCD Phase Register
    LCDPSbits.WFT = 1;        // B type waveform
	LCDPSbits.LP = 0x03;    // prescaler
	LCDPSbits.BIASMD = 0x01;
    //T1OSCEN = 1;    // activate the 32khz oscillator for the clock source

/*init LCD segments that will be used to drive Mentor LCD   */ 
    LCDSE0 = 0xFF;    //segs 0:7
    LCDSE1 = 0x07;	  //segs 8:10
    
/*Configure the LCD Control Register*/  
 	LCDCON = 0;		//Clear the control register
    SLPEN = 0;		//Driver module enabled during sleep 
    WERR = 0;		//No LCD Write Error
    LCDCONbits.CS = 0x10;		//LFINTOSC configured as clock source
    LCDCONbits.LMUX = 0x2;    //1/3 mux

/* clear ALL SEGMENT DATA */
    LCDDATA0 = 0;
    LCDDATA1 = 0;
    
    LCDDATA3 = 0;
    LCDDATA4 = 0;
    
    LCDDATA6 = 0;
    LCDDATA7 = 0;
        
    LCDIF = 0;		//Clear the LCD Interrupt flag im the PIR2 register

/*Configure Reference ladder control */
    LCDRL = 0x30;			//Set to internal ref, max power

/*Configure LCD reference voltate register*/
    LCDREF = 0;		//Clear the LCDREF register
    LCDIRE = 1;		//Internal reference is enabled
    LCDIRS = 0;		//contrast source is VDD
    LCDIRI = 0;		//LCD internal FVR buffer ignores LCD ref ladder power mode
	//VLCD1PE = 1; 	//Enable pin 1 internal reference
	//VLCD2PE = 1; 	//Enable pin 2 internal ref
	//VLCD3PE = 1;	//Enable pin 3 internal ref

/*Configure contrast*/
    LCDCST = 0;     // maximum contrast
   
	LCDEN = 1;		//enable the LCD engine
}

/****************************************************************************
  Function:
    void lcd_display_off(void)

  Summary:
    Turn off the LCD peripheral.  Leave the display configured.

  Description:
    This function is needed to generate a blinking display without modifying
    all the segment data.
 
  Precondition:
    None

  Parameters:
    None

  Returns:
    None

  Remarks:
    
  ***************************************************************************/
void lcd_display_off(void)
{
    LCDEN = 0;
}

/****************************************************************************
  Function:
    void lcd_display_on(void)

  Summary:
    Turn on the LCD peripheral.  Leave the display configured.

  Description:
    This function is needed to generate a blinking display without modifying
    all the segment data.
 
  Precondition:
    None

  Parameters:
    None

  Returns:
    None

  Remarks:
    
***************************************************************************/
void lcd_display_on(void)
{
    LCDEN = 1;
}

/****************************************************************************
  Function:
    BOOL lcd_display_digits(BCD_TYPE b)

  Summary:
    Render the 4 BCD digits 0-9, passed in mmDisp

  Description:
    This function checks the Write Allow bit to determine if it is ok to modify
    the LCD segments registers.  Write Allow could be false in Type B waveforms.
    If the Write Allow flag is true, this function accepts the numbers for
    display on the LCD. It renders the 7 segment data as quickly as possible by 
    a 2 level mapping of digits to segments and then segments to LCD segments.
    This function returns TRUE or FALSE based upon the state of WA.
 
  Precondition:
    None

  Parameters:
    BCD_TYPE b : digits to render

  Returns:
    BOOL TRUE if display was updated.
         FALSE if the display was not updated.

  Remarks:
    It is possible that this function will return false and thereby leave the
    in the old state. 
    If you are modifying other icons on the glass (decimal points, symbols)
    test the result of this function and only modify the segments if this returns true.
    As long as you are quick, the WA bit will still be true and allow writes.
  ***************************************************************************/

BOOL mmDisplayDigits(mmDisp MentorLCD)
{

    // Map Digit 3
    UINT8   val;

// The long list of IF statements was the fastest code as of HITEC 9.65PL1
  
  while(!WA);    //wait for controller to be ready.
    val = segment_data[MentorLCD.digit0].val;
        if(val & SEG_A)
        {
            A1 = 1;
        }

        if(!(val & SEG_A))
        {
            A1 = 0;
        }

        if(val & SEG_B)
        {
            B1 = 1;
        }

        if(!(val & SEG_B))
        {
            B1 = 0;
        }

        if(val & SEG_C)
        {
            C1 = 1;
        }

        if(!(val & SEG_C))
        {
            C1 = 0;
        }

        if(val & SEG_D)
        {
            D1 = 1;
        }

        if(!(val & SEG_D))
        {
            D1 = 0;
        }

        if(val & SEG_E)
        {
            E1 = 1;
        }

        if(!(val & SEG_E))
        {
            E1 = 0;
        }

        if(val & SEG_F)
        {
            F1 = 1;
        }

        if(!(val & SEG_F))
        {
            F1 = 0;
        }

        if(val & SEG_G)
        {
            G1 = 1;
        }

        if(!(val & SEG_G))
        {
            G1 = 0;
        }

        val = segment_data[MentorLCD.digit1].val;
        if(val & SEG_A)
        {
            A2 = 1;
        }

        if(!(val & SEG_A))
        {
            A2 = 0;
        }

        if(val & SEG_B)
        {
            B2 = 1;
        }

        if(!(val & SEG_B))
        {
            B2 = 0;
        }

        if(val & SEG_C)
        {
            C2 = 1;
        }

        if(!(val & SEG_C))
        {
            C2 = 0;
        }

        if(val & SEG_D)
        {
            D2 = 1;
        }

        if(!(val & SEG_D))
        {
            D2 = 0;
        }

        if(val & SEG_E)
        {
            E2 = 1;
        }

        if(!(val & SEG_E))
        {
            E2 = 0;
        }

        if(val & SEG_F)
        {
            F2 = 1;
        }

        if(!(val & SEG_F))
        {
            F2 = 0;
        }

        if(val & SEG_G)
        {
            G2 = 1;
        }

        if(!(val & SEG_G))
        {
            G2 = 0;
        }

        val = segment_data[MentorLCD.digit2].val;
        if(val & SEG_A)
        {
            A3 = 1;
        }

        if(!(val & SEG_A))
        {
            A3 = 0;
        }

        if(val & SEG_B)
        {
            B3 = 1;
        }

        if(!(val & SEG_B))
        {
            B3 = 0;
        }

        if(val & SEG_C)
        {
            C3 = 1;
        }

        if(!(val & SEG_C))
        {
            C3 = 0;
        }

        if(val & SEG_D)
        {
            D3 = 1;
        }

        if(!(val & SEG_D))
        {
            D3 = 0;
        }

        if(val & SEG_E)
        {
            E3 = 1;
        }

        if(!(val & SEG_E))
        {
            E3 = 0;
        }

        if(val & SEG_F)
        {
            F3 = 1;
        }

        if(!(val & SEG_F))
        {
            F3 = 0;
        }

        if(val & SEG_G)
        {
            G3 = 1;
        }

        if(!(val & SEG_G))
        {
            G3 = 0;
        }

        val = MentorLCD.dispsym;
        if(val & DP_1)
        {
            DP1 = 1;
        }

        if(!(val & DP_1))
        {
            DP1 = 0;
        }

        if(val & DP_2)
        {
            DP2 = 1;
        }

        if(!(val & DP_2))
        {
            DP2 = 0;
        }

        if(val & MINUS_)
        {
            MINUS = 1;
        }

        if(!(val & MINUS_))
        {
            MINUS = 0;
        }
        
        if(val & C1_C2)
        {
            CX = 1;
        }

        if(!(val & C1_C2))
        {
            CX = 0;
        }
    return(1);
}

void mmLCDClear(mmDisp disp)
{
    unsigned int i;  
  	disp.digit0 = 8;
	disp.digit1 = 8;
	disp.digit2 = 8;
	disp.dispsym = MINUS_|DP_1|DP_2|C1_C2;
	mmDisplayDigits(disp);
	for(i=0;i<0xA000;i++);    //short delay
	LCDEN = 0;   //turn off the LCD}
}

void mmDisplayOpr(void)
  {
    A1 = B1 = C1 = D1 = E1 =F1 = 1;   //turn on "0" character on digit 1.
    G1 = 0;
    A2 = B2 = E2 = F2 = G2 = 1;		//turn on "P" character on digit 2.
    C2 = D2 = 0;
    E3 = G3 = 1;					//turn on "r" Character on digit 3.
    A3 = B3 = C3 = D3 = F3 = 0;
   }	